<script lang="ts" setup>
import type { OpenCallbackMeta as IconSelectModalOpenCallbackMeta } from '@/components/IconSelectModal/type'
import type { OpenCallbackMeta } from '@/components/JumpLinkModal/type'
import { ENavigation01IconType, ENavigation01Style, type Navigation01Item } from '@/api/designer/model'
import BlockOpts from '@/components/CompAttr/BlockOpts.vue'
import CompStyle from '@/components/CompAttr/CompStyle.vue'
import ContainerMask from '@/components/CompAttr/ContainerMask.vue'
import { JumpType, JumpTypeMap, type Navigation01ComponentMeta } from '@/definitions/type'
import { useCompRefs } from '@/hooks/useCompRefs'
import { useCompStyle } from '@/hooks/useCompStyle'
import { useInstStore } from '@/stores'
import { removeItem, sortItem } from '@/utils/helper'
import { buildShortUUID } from '@/utils/uuid'
import { Input, Popconfirm, Radio, RadioGroup } from 'ant-design-vue'
import { ref } from 'vue'

defineOptions({
  name: 'Navigation01Attr',
  inheritAttrs: true,
})
const instStore = useInstStore()
const { activeRender } = useCompStyle<Navigation01ComponentMeta>()
function createNavigation01Item(): Navigation01Item {
  return {
    icon: '',
    iconRules: {
      min: 2,
      required: true,
    },
    jumpType: JumpType.None as any,
    title: '',
    titleRules: {
      min: 2,
      required: true,
    },
    id: buildShortUUID(),
    jumpTitle: '',
    jumpUrl: '',
    jumpValue: '',
    iconUseThemeColor: true,
  }
}
function handleAddItem() {
  if (!activeRender.value)
    return
  handleChooseIcon(createNavigation01Item())
}
function handleRemoveItem(item: Navigation01Item) {
  if (!activeRender.value)
    return
  removeItem(activeRender.value.config.items!, l => l.id === item.id)
}
function handleSort(item: Navigation01Item, type: 'up' | 'down') {
  sortItem(activeRender.value!.config.items!, l => l.id === item.id, type)
}

const { JumpLinkModalRef, IconSelectModalRef } = useCompRefs()
const currentJumpItem = ref<Nullable<Navigation01Item>>()
function handleChooseJumpLink(item: Navigation01Item) {
  if (JumpLinkModalRef.value) {
    currentJumpItem.value = item
    JumpLinkModalRef.value.open({
      jumpType: item.jumpType,
      jumpTitle: item.jumpTitle,
      jumpUrl: item.jumpUrl,
      jumpValue: item.jumpValue,
    }, chooseJumpCallback)
  }
}
function handleRemoveItemJumpLink(item: Navigation01Item) {
  item.jumpType = JumpType.None as any
  item.jumpTitle = ''
  item.jumpUrl = ''
  item.jumpValue = ''
}
function chooseJumpCallback(meta: OpenCallbackMeta) {
  if (activeRender.value && currentJumpItem.value && meta.applied) {
    const index = activeRender.value.config.items!.findIndex(l => l.id === currentJumpItem.value!.id)
    if (~index) {
      activeRender.value.config.items![index] = {
        ...activeRender.value.config.items![index],
        ...meta.value,
      }
    }
  }
  currentJumpItem.value = null
}
function handleChooseIcon(item: Navigation01Item) {
  if (IconSelectModalRef.value && activeRender.value) {
    currentJumpItem.value = item
    IconSelectModalRef.value.open({
      icon: {
        icon: item.icon,
        iconColor: item.iconColor,
        id: item.id,
        iconUseThemeColor: item.iconUseThemeColor,
      },
      iconType: activeRender.value.config.iconType,
    }, chooseIconCallback)
  }
}
function chooseIconCallback(meta: IconSelectModalOpenCallbackMeta) {
  if (activeRender.value && currentJumpItem.value && meta.applied) {
    const index = activeRender.value.config.items!.findIndex(l => l.id === currentJumpItem.value!.id)
    if (~index) {
      activeRender.value.config.items![index] = {
        ...activeRender.value.config.items![index],
        ...meta.value.icon,
      }
    }
    else {
      activeRender.value.config.items!.push({
        ...currentJumpItem.value,
        ...meta.value.icon,
      })
    }
  }
  currentJumpItem.value = null
}
function handleChangeIconType() {
  if (activeRender.value) {
    activeRender.value.config.items?.forEach((item) => {
      item.icon = ''
      item.iconColor = ''
    })
  }
}
</script>

<template>
  <div v-if="activeRender">
    <div class="setting-block">
      <div class="title-label">
        导航样式
      </div>
      <div class="inline-control">
        <div class="inline-control-label">
          一行
        </div>
        <div class="inline-control-block">
          <RadioGroup v-model:value="activeRender.config.style">
            <Radio :value="ENavigation01Style.三个">
              3个
            </Radio>
            <Radio :value="ENavigation01Style.四个">
              4个
            </Radio>
            <Radio :value="ENavigation01Style.五个">
              5个
            </Radio>
          </RadioGroup>
        </div>
      </div>
    </div>
    <div class="setting-block">
      <div class="title-label">
        导航内容
      </div>
      <div class="inline-control">
        <div class="inline-control-label">
          图标类型
        </div>
        <div class="inline-control-block">
          <RadioGroup v-model:value="activeRender.config.iconType" @change="handleChangeIconType">
            <Radio v-for="item in activeRender.config.iconTypeOptions" :key="item.value" :value="item.value">
              {{ item.label }}
            </Radio>
          </RadioGroup>
        </div>
      </div>
      <!-- 图片列表 -->
      <div class="flex flex-col w-full gap-3 mt-3">
        <!-- item for loop -->
        <div v-for="(item, index) in activeRender.config.items" :key="item.id" class="relative w-full pr-8">
          <!-- 灰色块 -->
          <div class="block-item">
            <div class="block-left" :class="item.icon ? 'has-icon' : ''" @click="handleChooseIcon(item)">
              <img
                v-if="!item.icon" src="/images/upload-placeholder.png" :width="32" :height="32"
                class="block w-32px h-32px mx-auto mt-4"
              >
              <div
                v-else-if="activeRender.config.iconType === ENavigation01IconType.矢量图标"
                class="text-48px !leading-none w-full h-full flex justify-center items-center iconfont"
                :class="item.icon" :style="{ color: item.iconUseThemeColor ? instStore.detail?.themeColor : item.iconColor }"
              />
              <img
                v-else-if="activeRender.config.iconType === ENavigation01IconType.图片图标" :src="item.icon" :width="64"
                :height="64" class="block w-64px h-64px object-contain"
              >
              <ContainerMask class="block-left-mask" />
            </div>
            <div class="block-right">
              <div class="block-right-item">
                <div class="block-right-item-label">
                  标题
                </div>
                <Input v-model:value="item.title" placeholder="导航文本" style="flex: 1;" />
              </div>
              <div class="block-right-item">
                <div class="block-right-item-label">
                  链接
                </div>
                <!-- CASE: 未选择链接 -->
                <div
                  v-if="(item.jumpType as any) === JumpType.None"
                  class="cursor-pointer text-primary-app text-sm flex items-center" @click="handleChooseJumpLink(item)"
                >
                  选择跳转到的页面<i class="i-ant-design:right-outlined w-4 h-4 ml-1" />
                </div>
                <!-- CASE: 已选择链接 -->
                <div v-else class="flex-1 flex flex-row items-center">
                  <div class="flex-1 w-0 truncate text-main-app text-sm">
                    {{ JumpTypeMap.get(item.jumpType as any) }} | {{ item.jumpTitle }}
                  </div>
                  <i
                    class="i-ant-design:edit-outlined w-4 h-4 cursor-pointer text-primary-app flex-none"
                    @click="handleChooseJumpLink(item)"
                  />
                  <Popconfirm
                    ok-text="确定" cancel-text="取消" title="确定要删除该链接吗?" placement="left"
                    @confirm="handleRemoveItemJumpLink(item)"
                  >
                    <i class="i-ant-design:delete-outlined w-4 h-4 cursor-pointer text-primary-app flex-none" />
                  </Popconfirm>
                </div>
              </div>
            </div>
          </div>
          <!-- 灰色块操作 -->
          <BlockOpts
            :item="item" :disabled-up="index === 0"
            :disabled-down="index === activeRender.config.items!.length - 1" @remove="handleRemoveItem"
            @sort="handleSort"
          />
        </div>
      </div>
      <!-- 添加图片按钮 -->
      <AddButton @click="handleAddItem">
        添加导航
      </AddButton>
    </div>
    <CompStyle />
  </div>
</template>

<style lang="less" scoped>
.setting-block {
  @apply mb-6;
}

.title-label {
  color: var(--app-text-color-main);
  margin-bottom: 14px;
  @apply text-sm font-700;
}

.block-item {
  background: #FAFAFF;
  @apply flex flex-row items-center gap-10px p-14px box-border rounded;

  .block-left {
    width: 64px;
    height: 64px;
    border: 1px solid #EEE;
    @apply rounded overflow-hidden relative flex-none bg-white;

    &.has-icon:hover .block-left-mask {
      @apply opacity-100;
    }
  }

  .block-right {
    @apply flex-1 w-0 flex flex-col gap-10px justify-center;

    .block-right-item {
      @apply flex flex-row items-center gap-2;
    }

    .block-right-item-label {
      color: var(--app-text-color-main);
      @apply text-sm flex-none;
    }
  }
}
</style>

<style lang="less" scoped>
.inline-control {
  @apply flex flex-row gap-8 items-start;

  .inline-control-label {
    color: var(--app-text-color-second);
    @apply text-sm flex-none;
  }

  .inline-control-block {
    color: var(--app-text-color-main);
    @apply text-sm;
  }
}
</style>
